package pl.vanta.utils.commons.formats;

import java.text.FieldPosition;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.ParsePosition;

public class RomanNumberFormat extends NumberFormat
{
	private static final long		serialVersionUID	= -6089496676325934022L;

	private final static String[]	BASIC_ROMAN_NUMBERS	= { "(M)", "(D)", "(C)", "(L)", "(X)", "(V)", "(IV)", "M",
			"CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I" };
	private final static int[]		BASIC_VALUES		= { 1000000, 500000, 100000, 50000, 10000, 5000, 4000, 1000,
			900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };

	@Override
	public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos)
	{
		return format(Math.round(number), toAppendTo, pos);
	}

	@Override
	public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos)
	{
		return toAppendTo.append(arabic2roman((int) number));
	}

	@Override
	public Number parse(String source, ParsePosition parsePosition)
	{
		return roman2arabic(source);
	}

	@Override
	public Number parse(String source) throws ParseException
	{
		return this.parse(source, null);
	}

	private int roman2arabic(String roman)
	{
		int value = 0;
		int index = 0;

		String r = roman.toUpperCase();

		for (int i = 0; i < BASIC_ROMAN_NUMBERS.length; i++)
		{
			while (r.startsWith(BASIC_ROMAN_NUMBERS[i], index))
			{
				value += BASIC_VALUES[i];
				index += BASIC_ROMAN_NUMBERS[i].length();
			}
		}

		return value;
	}

	private String arabic2roman(int arabic)
	{
		String romanString = "";
		int remainder = arabic;

		for (int i = 0; i < BASIC_VALUES.length; i++)
		{
			while (remainder >= BASIC_VALUES[i])
			{
				romanString += BASIC_ROMAN_NUMBERS[i];
				remainder -= BASIC_VALUES[i];
			}
		}

		return romanString;
	}
}